package com.rybbaby.tss.platform.sysSchool.service.imp;

import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.rybbaby.tss.core.consts.RoleConsts;
import com.rybbaby.tss.core.enums.MemberPropertyEnum;
import com.rybbaby.tss.core.enums.SchoolBusinessTypeEnum;
import com.rybbaby.tss.core.utils.*;
import com.rybbaby.tss.core.web.service.imp.BaseServiceImp;
import com.rybbaby.tss.platform.initializer.HandlePermissionsInitializer;
import com.rybbaby.tss.platform.initializer.MenuPermissionsInitializer;
import com.rybbaby.tss.platform.sysAdminUser.entity.SysAdminUser;
import com.rybbaby.tss.platform.sysAdminUser.service.ISysAdminUserService;
import com.rybbaby.tss.platform.sysAdminUserJoinSysRole.entity.SysAdminUserJoinSysRole;
import com.rybbaby.tss.platform.sysAdminUserJoinSysRole.service.ISysAdminUserJoinSysRoleService;
import com.rybbaby.tss.platform.sysConfig.entity.SysConfig;
import com.rybbaby.tss.platform.sysConfig.service.ISysConfigService;
import com.rybbaby.tss.platform.sysHandlePermissions.entity.SysHandlePermissions;
import com.rybbaby.tss.platform.sysHandlePermissions.service.ISysHandlePermissionsService;
import com.rybbaby.tss.platform.sysRole.entity.SysRole;
import com.rybbaby.tss.platform.sysRole.service.ISysRoleService;
import com.rybbaby.tss.platform.sysRoleGroup.entity.SysRoleGroup;
import com.rybbaby.tss.platform.sysRoleGroup.service.ISysRoleGroupService;
import com.rybbaby.tss.platform.sysRoleJoinSysMenuPermissions.entity.SysRoleJoinSysMenuPermissions;
import com.rybbaby.tss.platform.sysRoleJoinSysMenuPermissions.service.ISysRoleJoinSysMenuPermissionsService;
import com.rybbaby.tss.platform.sysSchool.entity.SysSchool;
import com.rybbaby.tss.platform.sysSchool.service.ISysSchoolService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.*;

/**
 * @author 雷春琼
 * @description 园所数据库操作服务实现
 * @createDate 2017-08-09 上午11:00:39
 */
@Service
@Transactional
public class SysSchoolServiceImp extends BaseServiceImp<SysSchool> implements ISysSchoolService {
    @Autowired
    private ISysRoleGroupService sysRoleGroupService;
    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private ISysRoleJoinSysMenuPermissionsService sysRoleJoinSysMenuPermissionsService;
    @Autowired
    private ISysHandlePermissionsService handlePermissionsService;
    @Autowired
    private ISysAdminUserService sysAdminUserService;
    @Autowired
    private ISysAdminUserJoinSysRoleService sysAdminUserJoinSysRoleService;
    @Autowired
    private ISysConfigService sysConfigService;


    /**
     * 保存园所对象
     *
     * @param entity
     * @return
     */
    public Serializable save(Object loginUserId_obj, SysSchool entity, String sessionId, String schoolAccount, String educationalAccount, String accountPhone, String educationalPhone, String userPassword) throws Exception {
        String createUserId = loginUserId_obj == null ? null : loginUserId_obj.toString();
        entity.setCreateUserId(createUserId);
        entity.setCreateTime(new java.sql.Timestamp(System.currentTimeMillis()));
        //生成园所编码
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("sequenceName", "SEQUENCE_UMS_SCHOOL_CODE");
        if (entity.getType() == 1) {
            paramsMap.put("businessType", SchoolBusinessTypeEnum.亲子直营园.value());
        } else if (entity.getType() == 2) {
            paramsMap.put("businessType", SchoolBusinessTypeEnum.亲子加盟园.value());
        }
        paramsMap.put("provinceId", entity.getSchoolProvince());
        String resultCode = CodeGenUtil.getCodeGen(paramsMap);
        Gson gson = new Gson();
        Map<String, Object> map = gson.fromJson(resultCode, new TypeToken<Map<String, Object>>() {
        }.getType());
        if (Double.parseDouble(map.get("resCode") + "") == 200) {
            entity.setSchoolCode(map.get("data").toString());
        }

        entity.setSchoolContractCode(entity.getSchoolCode());
        Serializable schoolId = this.save(entity);
        if (schoolId != null) {
            //设置默认角色分组、角色、菜单、操作权限
            initData(entity, createUserId, schoolId);
            if (StringUtils.isNotBlank(schoolAccount)) {//园长
                try {
                    autoSaveAdminUser(createUserId, sessionId, schoolAccount, accountPhone, userPassword, schoolId, "1", RoleConsts.TSS_ROLE_KINDERGARTEN_LEADER);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            if (StringUtils.isNotBlank(educationalAccount)) {//教务
                try {
                    autoSaveAdminUser(createUserId, sessionId, educationalAccount, educationalPhone, userPassword, schoolId, "2", RoleConsts.TSS_TEACHING_AFFAIRS);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return schoolId;
    }

    private void autoSaveAdminUser(String createUserId, String sessionId, String educationalAccount, String educationalPhone, String userPassword, Serializable schoolId, String s, String tssTeachingAffairs) throws Exception {
        SysAdminUser adminUser;
        adminUser = new SysAdminUser();
        adminUser.setSchoolId(schoolId.toString());
        adminUser.setUserName(educationalAccount);
        adminUser.setRealName(educationalAccount);
        adminUser.setPhoneNumber(educationalPhone);
        adminUser.setIsForbidden(false);
        adminUser.setIsCanDelete(true);
        adminUser.setIsOpenAccount(true);
        adminUser.setIsOnline(0);
        adminUser.setPost(s);
        adminUser.setCreateTime(new Timestamp(System.currentTimeMillis()));
        adminUser.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
        adminUser.setUserPassword(StringUtils.isNotBlank(userPassword) ? userPassword : "qzy123456");

        //生成员工编码
        //获取园所码
        SysSchool sysSchool = this.get(schoolId);
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("sequenceName", "SEQUENCE_TSS_SYS_ADMIN_USER_CONTRACT_CODE");
        paramsMap.put("schoolCode", sysSchool.getSchoolCode());
        paramsMap.put("memberProperty", MemberPropertyEnum.员工.value());
        String resultCode = CodeGenUtil.getCodeGen(paramsMap);
        Gson gson = new Gson();
        Map<String, Object> map = gson.fromJson(resultCode, new TypeToken<Map<String, Object>>() {
        }.getType());
        if (Double.parseDouble(map.get("resCode") + "") == 200) {
            adminUser.setAdminUserCode(map.get("data").toString());
        }
        //设置加密并保存
        Serializable newUserId = this.sysAdminUserService.save(adminUser, sessionId, createUserId);
        this.setPassword(newUserId, adminUser);
        //绑定角色
        bindRole(createUserId, schoolId, newUserId, tssTeachingAffairs);
    }

    /**
     * 设置默认角色分组、角色、菜单、操作权限
     *
     * @param entity       园所对象
     * @param createUserId 创建人id
     * @param schoolId     园所Id
     */
    private void initData(SysSchool entity, String createUserId, Serializable schoolId) {
        //角色分组
        SysRoleGroup roleGroup = new SysRoleGroup();
        roleGroup.setCode(schoolId.toString());
        roleGroup.setName(entity.getSchoolName());
        roleGroup.setCreateTime(new Timestamp(System.currentTimeMillis()));
        Serializable groupId = this.sysRoleGroupService.save(roleGroup);
        if (groupId != null) {
            //角色
            List<SysRole> defaultRoles = new ArrayList<>();
            SysConfig tssSchoolDefaultRoleConfigJson = this.sysConfigService.findUniqueByProperty("name", "tssSchoolDefaultRoleConfigJson");
            if (tssSchoolDefaultRoleConfigJson != null && StringUtils.isNotBlank(tssSchoolDefaultRoleConfigJson.getValue())) {
                JSONObject roleJsonConfig = null;
                String configFormatErrorMsg = "默认角色配置参数格式错误!";
                try {
                    roleJsonConfig = JSONObject.fromObject(tssSchoolDefaultRoleConfigJson.getValue());
                } catch (Exception e) {
                    throw new RuntimeException(configFormatErrorMsg);
                }
                Set<String> roleNames = roleJsonConfig.keySet();
                for (String roleName : roleNames) {
                    SysRole sysRole = new SysRole();
                    sysRole.setCreateTime(new Timestamp(System.currentTimeMillis()));
                    sysRole.setCreateUserId(createUserId);
                    sysRole.setGroupId(groupId.toString());
                    sysRole.setIsCanDelete(true);
                    sysRole.setIsForbidden(false);
                    sysRole.setRoleName(roleName);
                    defaultRoles.add(sysRole);
                }
                List<Serializable> newRoleIds = this.sysRoleService.hibernateBatchSave(defaultRoles);
                List<SysRole> sysRoles = this.sysRoleService.loadByMultipleId(SysRole.class, newRoleIds);
                if (sysRoles != null && !sysRoles.isEmpty()) {
                    List<SysHandlePermissions> newHandlePermissions = new ArrayList<>();//菜单操作权限分配
                    for (SysRole role : sysRoles) {
                        JSONArray menus = roleJsonConfig.getJSONArray(role.getRoleName());
                        if (menus != null && !menus.isEmpty()) {
                            int weight = 1;
                            for (int i = 0, size = menus.size(); i < size; i++) {
                                JSONObject menuJsonConfig = menus.getJSONObject(i);
                                String menuId;
                                if (menuJsonConfig.containsKey("menuId")) {
                                    menuId = menuJsonConfig.getString("menuId");
                                } else {
                                    continue;
                                }
                                Serializable newRoleMenuAllotId = null;
                                if (StringUtils.isNotBlank(menuId)) {
                                    SysRoleJoinSysMenuPermissions roleJoinSysMenuPermissions = new SysRoleJoinSysMenuPermissions();
                                    roleJoinSysMenuPermissions.setRoleId(role.getId());
                                    roleJoinSysMenuPermissions.setMenuPermissionId(menuId);
                                    roleJoinSysMenuPermissions.setCreateTime(new Timestamp(System.currentTimeMillis()));
                                    roleJoinSysMenuPermissions.setCreateUserId(createUserId);
                                    roleJoinSysMenuPermissions.setWeight(weight++);
                                    newRoleMenuAllotId = this.sysRoleJoinSysMenuPermissionsService.save(roleJoinSysMenuPermissions);
                                } else {
                                    continue;
                                }
                                //角色设置默认菜单
                                if (newRoleMenuAllotId != null) {
                                    if (menuJsonConfig.containsKey("handleIds")) {
                                        JSONArray handleIds = menuJsonConfig.getJSONArray("handleIds");
                                        if (handleIds != null && !handleIds.isEmpty()) {
                                            List<SysHandlePermissions> handlePermissions = this.handlePermissionsService.loadByMultipleId(SysHandlePermissions.class, handleIds);
                                            if (handlePermissions != null && !handlePermissions.isEmpty()) {
                                                weight = 0;
                                                for (SysHandlePermissions handlePermission : handlePermissions) {
                                                    SysHandlePermissions hp = new SysHandlePermissions();
                                                    BeanUtils.copyProperties(handlePermission, hp, "id", "version", "createTime", "weight");
                                                    hp.setDefaultHandlePermissionId(handlePermission.getId());
                                                    hp.setRolePermissionAllotId(newRoleMenuAllotId.toString());
                                                    hp.setWeight(weight++);
                                                    hp.setCreateTime(new Timestamp(System.currentTimeMillis()));
                                                    newHandlePermissions.add(hp);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    //菜单设置默认操作权限
                    if (!newHandlePermissions.isEmpty()) {
                        this.handlePermissionsService.hibernateBatchSave(newHandlePermissions);
                    }
                    // 刷新缓存
                    MenuPermissionsInitializer.load();
                    HandlePermissionsInitializer.reloadHandlePermission();
                }
            }
        }
    }

    /**
     * 绑定角色
     *
     * @param createUserId 当前登录人id
     * @param schoolId     园所Id
     * @param newUserId    需要绑定角色的用户id
     * @param roleName     需要绑定的角色名称
     */
    private void bindRole(String createUserId, Serializable schoolId, Serializable newUserId, String roleName) {
        SysRoleGroup roleGroup = this.sysRoleGroupService.findUniqueByProperty("code", schoolId);
        if (roleGroup != null) {
            DetachedCriteria dc1 = DetachedCriteria.forClass(SysRole.class);
            dc1.add(Restrictions.eq("groupId", roleGroup.getId()));
            dc1.add(Restrictions.eq("roleName", roleName));
            List<SysRole> roles = this.sysRoleService.findByDetached(dc1);
            if (roles != null && !roles.isEmpty()) {
                SysRole role = roles.get(0);
                if (role != null) {
                    SysAdminUserJoinSysRole sysAdminUserJoinSysRole = new SysAdminUserJoinSysRole();
                    sysAdminUserJoinSysRole.setAdminUserId(newUserId.toString());
                    sysAdminUserJoinSysRole.setRoleId(role.getId());
                    sysAdminUserJoinSysRole.setCreateTime(new Timestamp(System.currentTimeMillis()));
                    sysAdminUserJoinSysRole.setCreateUserId(createUserId.toString());
                    this.sysAdminUserJoinSysRoleService.save(sysAdminUserJoinSysRole);
                }
            }
        }
    }

    private void setPassword(Serializable newId, SysAdminUser adminUser) {
        // 密码加密,用jdbc查询防止缓存
        String sql = "SELECT createTime FROM sys_admin_user WHERE id=?";
        Map<String, Object> newstMatp = this.sysAdminUserService.findOneForJdbc(sql, new Object[]{newId});
        Object createTime = newstMatp.get("createTime");
        if (createTime != null && createTime instanceof Timestamp) {
            adminUser.setCreateTime(Timestamp.valueOf(createTime.toString()));
        }
        if (StringUtils.isNotBlank(adminUser.getUserPassword())) {
            String encryptPassword = EncryptPasswordUtil.encryptAdminPassword(adminUser.getId(), adminUser.getCreateTime(), adminUser.getUserPassword());
            adminUser.setUserPassword(encryptPassword);
            this.sysAdminUserService.updateEntitiy(adminUser);
        }
    }
}
